package cn.tsvtc.shop.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.extra.mail.MailUtil;
import cn.tsvtc.shop.constant.RedisConstant;
import cn.tsvtc.shop.entity.ResultMessage;
import cn.tsvtc.shop.feign.SmsFeign;
import cn.tsvtc.shop.mapper.UserMapper;
import cn.tsvtc.shop.pojo.RegisterEmailUser;
import cn.tsvtc.shop.pojo.RegisterPhoneUser;
import cn.tsvtc.shop.pojo.User;
import cn.tsvtc.shop.service.CodeService;
import cn.tsvtc.shop.service.UserService;
import cn.tsvtc.shop.utils.CodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author: Athena
 * @date: 2020/10/29 17:18
 * @description:
 */
@Service
@Slf4j
public class CodeServiceImpl implements CodeService {

    private SmsFeign smsFeign;

    private UserMapper userMapper;

    private RedisTemplate redisTemplate;

    @Autowired
    public CodeServiceImpl( RedisTemplate redisTemplate, SmsFeign smsFeign,UserMapper userMapper){
        this.userMapper=userMapper;
        this.redisTemplate=redisTemplate;
        this.smsFeign=smsFeign;
    }

    /**
     * 发送短信验证码
     *
     * @param phone
     * @return Boolean
     */
    @Override
    public Boolean sendSmsCode(String phone) {
        //先检测redis中是否有对应电话号的验证码条目，若有则返回失败
        Object value = redisTemplate.opsForValue().get(RedisConstant.SHOP_REGISTER + phone);
        log.info("用户"+phone+"在redis里面存的是"+value);
        if(value!=null){
            //ResultMessage<String> failMessage = new ResultMessage<String>(false,"failed","您已获取过验证码了");
            //已获取过验证码,且未失效
            return false;
        }else {
            //1.先生成4位数字验证码
            String randomIntCodes = CodeUtils.getRandomIntCodes(4);
            //2.redis存入验证码
            redisTemplate.opsForValue().set(RedisConstant.SHOP_REGISTER+phone,randomIntCodes,1, TimeUnit.MINUTES);
            //3.发送验证码短信
            log.info("用户"+phone+"获取到的验证码为"+randomIntCodes);
            //Object o = redisTemplate.opsForValue().get(RedisConstant.SHOP_REGISTER + phone);

            //String send = smsFeign.send(phone, randomIntCodes);
            //log.info(send);

            ResultMessage<String> stringResultMessage = new ResultMessage<>();
            stringResultMessage.setData("成功");
            return true;
        }
    }

    /**
     * 发送邮件验证码
     *
     * @param user
     * @return Boolean
     */
    @Override
    public Boolean sendEmailCode(RegisterEmailUser user) {
        //1.先生成6位验证码
        String randomIntCodes = CodeUtils.getRandomAllCodes(6);
        try {
            //发送邮件

            //设置邮箱验证码
            redisTemplate.opsForValue().set(RedisConstant.SHOP_REGISTER+user.getMail(),randomIntCodes,1, TimeUnit.DAYS);
            String ip = null;
            try {
                ip = Inet4Address.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            String url = "http://localhost:8001/reg/active.action?e="+ Base64.encode(user.getMail())+"&c="+Base64.encode(randomIntCodes);

            String content=user.getMail()+",你好,欢迎注册喵喵喵商城! 请点击链接进行激活:  "+url+" ,激活链接一天内有效哦，喵喵喵";
            MailUtil.send(user.getMail(), "您的激活链接", content, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 激活邮箱注册的账户
     *
     * @param  email,code
     * @return
     */
    @Override
    public Boolean activeUser(String email,String code) {
        String mailActive = Base64.decodeStr(email);
        String codeActive = Base64.decodeStr(code);
        log.info("mailActive===>"+mailActive);
        log.info("codeActive===>"+codeActive);
        //检查是否存在
        Object activeCodeFromRedis = redisTemplate.opsForValue().get(RedisConstant.SHOP_REGISTER + mailActive);
        if (activeCodeFromRedis != null) {
            String userCode= (String) activeCodeFromRedis;
            //检查验证码是否正确
            User temp=null;
            if(userCode.equalsIgnoreCase(codeActive)){
                //正确,则从redis读入对象
                //从redis读取user列表
//                List<User> usersFromRedis = redisTemplate.opsForList().range("t_user", 0, -1);
//                for (User fromRedi : usersFromRedis) {
//                    if(fromRedi.getEmail().equals(mailActive)){
//                        temp=fromRedi;
//                    }
//                }

                Map<Long,User> map = redisTemplate.opsForHash().entries("t_user");
                for(Map.Entry<Long,User> entry : map.entrySet()){
                    Long mapKey = entry.getKey();
                    User mapValue = entry.getValue();
                    if (mapValue.getEmail()!=null){
                        if (mapValue.getEmail().equals(mailActive)){
                            temp=mapValue;
                        }
                    }
                }

                //更新redis数据和数据库
                //激活
                temp.setStatus(1);
                // 重新存入redis
                //redisTemplate.opsForList().trim("t_user",-1,0);
                redisTemplate.opsForHash().put("t_user",temp.getId(),temp);
                //存入数据库
                int result = userMapper.updateByPrimaryKeySelective(temp);
                if(result==1){
                    //删除redis中存储的临时激活数据
                    redisTemplate.opsForValue().getOperations().delete(RedisConstant.SHOP_REGISTER + mailActive);
                    return true;
                }else {
                    //数据库存入失败
                    return false;
                }
            }else {
                //链接传过来的验证码不正确
                return false;
            }
        }else {
            //redis存的邮箱验证码为空
            return false;
        }
    }
}
